﻿package morn.core.managers
{
    import __AS3__.vec.*;
    import com.sh.game.consts.*;
    import com.sh.game.global.*;
    import com.sh.game.util.*;
    import flash.events.*;
    import flash.utils.*;
    import morn.core.handlers.*;

    public class MassLoaderManager extends EventDispatcher
    {
        private var _resLoaders:Vector.<ResLoader>;
        private var _maxLoader:int = 3;
        private var _loaderCount:int = 0;
        private var _resInfos:Array;
        private var _resMap:Object;
        private var _maxPriority:uint = 5;
        private var _failRes:Object;
        private var _retryNum:int = 3;
        private var _ioErrorRetry:int = 1;
        private var _isRoot:Boolean = false;
        private var _leisureLoader:Boolean = false;
        public var waiting:Boolean = false;
        private var _localLoader:Boolean = false;
        private var _checkId:uint = 0;
        private var _nextTime:int = 0;
        private var _lock:Boolean = false;
        public static var success:Object = new Object();
        public static var errors:Object = new Object();

        public function MassLoaderManager(param1:Boolean = false, param2:Boolean = false, param3:Boolean = false)
        {
            this._resLoaders = new Vector.<ResLoader>;
            this._resInfos = [];
            this._resMap = {};
            this._failRes = {};
            this._isRoot = param1;
            this._localLoader = param3;
            this._leisureLoader = param2;
            var _loc_4:int = 0;
            while (_loc_4 < this._maxPriority)
            {
                
                this._resInfos[_loc_4] = [];
                _loc_4++;
            }
            return;
        }// end function

        public function get loaderCount() : int
        {
            return this._loaderCount;
        }// end function

        public function loadResInfo(param1:ResInfo, param2:int = 0) : void
        {
            if (param2 > 0)
            {
                this._failRes[param1.url] = Math.max(0, this.retryNum - param2);
            }
            param1.loader = null;
            var _loc_3:* = ResLoader.getResLoaded(param1.url);
            if (_loc_3 != null)
            {
                this.endLoad(param1, _loc_3, 0);
            }
            else
            {
                if (param1.url == null && Config.Log > LogType.ERROR)
                {
                    Logger.log("什么情况。。。url为null");
                }
                this._resMap[param1.url] = param1;
                this._resInfos[param1.priority].push(param1);
                this.checkNext();
            }
            return;
        }// end function

        public function resLoading(param1:String) : ResInfo
        {
            return this._resMap[param1];
        }// end function

        public function unload(param1:String, param2:Boolean = true) : Boolean
        {
            var _loc_3:ResInfo = null;
            var _loc_4:ResLoader = null;
            var _loc_5:ResInfo = null;
            var _loc_6:int = 0;
            if (this._resMap[param1])
            {
                _loc_4 = this._resMap[param1].loader;
                if (_loc_4)
                {
                    if (param2)
                    {
                        return false;
                    }
                    _loc_4.tryToCloseLoad();
                    this._resMap[param1].loader = null;
                    this._resLoaders.push(_loc_4);
                    var _loc_7:String = this;
                    var _loc_8:* = this._loaderCount - 1;
                    _loc_7._loaderCount = _loc_8;
                    if (!this._leisureLoader)
                    {
                        this.checkLeisure();
                    }
                }
                else
                {
                    _loc_5 = this._resMap[param1];
                    _loc_6 = this._resInfos[_loc_5.priority].indexOf(_loc_5);
                    if (_loc_6 > -1)
                    {
                        this._resInfos[_loc_5.priority].splice(_loc_6, 1);
                    }
                }
                this._resMap[param1].destroy();
                delete this._resMap[param1];
                if (param1 in this._failRes)
                {
                    delete this._failRes[param1];
                }
                this.checkNext();
                return true;
            }
            else if (this._isRoot)
            {
                return App.mloader2.unload(param1);
            }
            return false;
        }// end function

        public function sortQueue(param1:int, param2:Function) : void
        {
            if (this._resInfos[param1])
            {
                (this._resInfos[param1] as Array).sort(param2);
            }
            return;
        }// end function

        protected function load(param1:String, param2:uint, param3:uint = 1, param4:Handler = null, param5:Handler = null, param6:Handler = null, param7:Boolean = true, param8:Object = null) : void
        {
            var _loc_11:ResInfo = null;
            if (!this._localLoader && ResLoader.hadCache(param1))
            {
                App.localLoader.load(param1, param2, param3, param4, param5, param6, param7, param8);
                return;
            }
            if (errors[param1])
            {
                if (param4 != null)
                {
                    param4.executeWith([null]);
                }
                return;
            }
            var _loc_9:* = new ResInfo();
            new ResInfo().url = param1;
            _loc_9.type = param2;
            _loc_9.completeHandlers.push(param4);
            _loc_9.progressHandlers.push(param5);
            _loc_9.errorHandlers.push(param6);
            _loc_9.isCacheContent = param7;
            _loc_9.data = param8;
            var _loc_10:* = ResLoader.getResLoaded(_loc_9.url);
            if (ResLoader.getResLoaded(_loc_9.url) != null)
            {
                this.endLoad(_loc_9, _loc_10, 0);
            }
            else
            {
                _loc_11 = App.mloader2.resLoading(param1);
                if (_loc_11 == null)
                {
                    _loc_11 = this._resMap[param1];
                }
                if (_loc_11 == null)
                {
                    this._resMap[param1] = _loc_9;
                    if (param3 == 99)
                    {
                        param3 = 0;
                        _loc_9.priority = param3;
                        this._resInfos[param3].unshift(_loc_9);
                    }
                    else
                    {
                        param3 = param3 < this._maxPriority ? (param3) : ((this._maxPriority - 1));
                        _loc_9.priority = param3;
                        this._resInfos[param3].push(_loc_9);
                    }
                    this.checkNext();
                }
                else
                {
                    _loc_11.completeHandlers.push(param4);
                    _loc_11.progressHandlers.push(param5);
                    _loc_11.errorHandlers.push(param6);
                }
            }
            return;
        }// end function

        private function checkNext() : void
        {
            var _loc_2:int = 0;
            var _loc_3:Array = null;
            var _loc_4:ResInfo = null;
            var _loc_5:* = undefined;
            if (this._lock)
            {
                return;
            }
            if (this._loaderCount >= this._maxLoader)
            {
                return;
            }
            if (this._leisureLoader)
            {
                _loc_2 = getTimer();
                if (this._nextTime > _loc_2)
                {
                    if (this._checkId == 0)
                    {
                        this._checkId = setTimeout(this.checkNext, 5000);
                    }
                    return;
                }
                else
                {
                    if (this._checkId > 0)
                    {
                        clearTimeout(this._checkId);
                        this._checkId = 0;
                    }
                    this._nextTime = _loc_2 + 5000;
                }
            }
            var _loc_1:int = 0;
            while (_loc_1 < this._maxPriority)
            {
                
                _loc_3 = this._resInfos[_loc_1];
                while (_loc_3.length > 0)
                {
                    
                    _loc_4 = _loc_3.shift();
                    if (_loc_4.url != null)
                    {
                        _loc_5 = ResLoader.getResLoaded(_loc_4.url);
                        if (_loc_5 != null)
                        {
                            this.endLoad(_loc_4, _loc_5, 0);
                            continue;
                        }
                        this.doLoad(_loc_4);
                        return;
                    }
                }
                _loc_1++;
            }
            if (hasEventListener(Event.COMPLETE))
            {
                dispatchEvent(new Event(Event.COMPLETE));
            }
            return;
        }// end function

        private function doLoad(param1:ResInfo) : void
        {
            var _loc_3:String = this;
            var _loc_4:* = this._loaderCount + 1;
            _loc_3._loaderCount = _loc_4;
            var _loc_2:* = this._resLoaders.length > 0 ? (this._resLoaders.pop()) : (new ResLoader());
            param1.loader = _loc_2;
            _loc_2.load(param1.url, param1.type, new Handler(this.loadComplete, [_loc_2, param1]), new Handler(this.loadProgress, [param1]), param1.isCacheContent, this._isRoot ? (2000) : (8000), this._failRes[param1.url]);
            if (!this._leisureLoader)
            {
                this.checkLeisure();
            }
            return;
        }// end function

        private function loadProgress(param1:ResInfo, param2:Number) : void
        {
            var _loc_3:Handler = null;
            for each (_loc_3 in param1.progressHandlers)
            {
                
                if (_loc_3 != null)
                {
                    _loc_3.executeWith([param2]);
                }
            }
            return;
        }// end function

        private function loadComplete(param1:ResLoader, param2:ResInfo, param3, param4:int) : void
        {
            this._resLoaders.push(param1);
            this.endLoad(param2, param3, param4);
            var _loc_5:String = this;
            var _loc_6:* = this._loaderCount - 1;
            _loc_5._loaderCount = _loc_6;
            if (!this._leisureLoader)
            {
                this.checkLeisure();
            }
            this.checkNext();
            return;
        }// end function

        public function checkLeisure() : void
        {
            if (!this._leisureLoader)
            {
                if (App.maploader.loaderCount + App.mloader.loaderCount + App.mloader2.loaderCount + App.mloader3.loaderCount <= 3 && App.mloader.loaderCount <= 1 && !App.leisureMloader.waiting)
                {
                    App.leisureMloader.unlock();
                }
                else
                {
                    App.leisureMloader.lock();
                }
            }
            return;
        }// end function

        private function endLoad(param1:ResInfo, param2, param3:int) : void
        {
            var _loc_5:int = 0;
            var _loc_6:int = 0;
            var _loc_7:Handler = null;
            var _loc_8:Handler = null;
            if (param2 == null)
            {
                _loc_5 = this._failRes[param1.url] || 0;
                _loc_6 = param3 == 2 ? (this._ioErrorRetry) : (this._retryNum);
                if (_loc_5 < _loc_6)
                {
                    if (this._isRoot)
                    {
                        delete this._resMap[param1.url];
                        App.mloader2.loadResInfo(param1, _loc_6 - _loc_5);
                    }
                    else
                    {
                        this._failRes[param1.url] = _loc_5 + 1;
                        this._resInfos[(this._maxPriority - 1)].push(param1);
                        param1.priority = this._maxPriority - 1;
                    }
                    return;
                }
                else
                {
                    for each (_loc_7 in param1.errorHandlers)
                    {
                        
                        if (_loc_7 != null)
                        {
                            _loc_7.executeWith([param1.url]);
                        }
                    }
                    errors[param1.url] = true;
                }
            }
            var _loc_4:* = param1.url;
            delete this._resMap[param1.url];
            if (param1.url in this._failRes)
            {
                delete this._failRes[param1.url];
            }
            try
            {
                for each (_loc_8 in param1.completeHandlers)
                {
                    
                    if (_loc_8 != null)
                    {
                        _loc_8.executeWith([param2]);
                    }
                }
            }
            catch (e:Error)
            {
            }
            param1.destroy();
            return;
        }// end function

        public function loadSWF(param1:String, param2:uint = 1, param3:Handler = null, param4:Handler = null, param5:Handler = null, param6:Boolean = true, param7:Object = null) : void
        {
            this.load(param1, ResLoader.SWF, param2, param3, param4, param5, param6, param7);
            return;
        }// end function

        public function loadMSWF(param1:String, param2:uint = 1, param3:Handler = null, param4:Handler = null, param5:Handler = null, param6:Boolean = true, param7:Object = null) : void
        {
            this.load(param1, ResLoader.MSWF, param2, param3, param4, param5, param6, param7);
            return;
        }// end function

        public function loadBMD(param1:String, param2:uint = 1, param3:Handler = null, param4:Handler = null, param5:Handler = null, param6:Boolean = true, param7:Object = null) : void
        {
            this.load(param1, ResLoader.BMD, param2, param3, param4, param5, param6, param7);
            return;
        }// end function

        public function loadBM(param1:String, param2:uint = 1, param3:Handler = null, param4:Handler = null, param5:Handler = null, param6:Boolean = true, param7:Object = null) : void
        {
            this.load(param1, ResLoader.BM, param2, param3, param4, param5, param6, param7);
            return;
        }// end function

        public function loadAMF(param1:String, param2:uint = 1, param3:Handler = null, param4:Handler = null, param5:Handler = null, param6:Boolean = true, param7:Object = null) : void
        {
            this.load(param1, ResLoader.AMF, param2, param3, param4, param5, param6, param7);
            return;
        }// end function

        public function loadTXT(param1:String, param2:uint = 1, param3:Handler = null, param4:Handler = null, param5:Handler = null, param6:Boolean = true, param7:Object = null) : void
        {
            this.load(param1, ResLoader.TXT, param2, param3, param4, param5, param6, param7);
            return;
        }// end function

        public function loadDB(param1:String, param2:uint = 1, param3:Handler = null, param4:Handler = null, param5:Handler = null, param6:Boolean = true, param7:Object = null) : void
        {
            this.load(param1, ResLoader.DB, param2, param3, param4, param5, param6, param7);
            return;
        }// end function

        public function loadBYTE(param1:String, param2:uint = 1, param3:Handler = null, param4:Handler = null, param5:Handler = null, param6:Boolean = true, param7:Object = null) : void
        {
            this.load(param1, ResLoader.BYTE, param2, param3, param4, param5, param6, param7);
            return;
        }// end function

        public function get maxLoader() : int
        {
            return this._maxLoader;
        }// end function

        public function set maxLoader(param1:int) : void
        {
            this._maxLoader = param1;
            return;
        }// end function

        public function getResLoaded(param1:String)
        {
            return ResLoader.getResLoaded(param1);
        }// end function

        public function clearResLoaded(param1:String) : void
        {
            ResLoader.clearResLoaded(param1);
            return;
        }// end function

        public function get retryNum() : int
        {
            return this._retryNum;
        }// end function

        public function set retryNum(param1:int) : void
        {
            this._retryNum = param1;
            return;
        }// end function

        public function loadAssets(param1:Array, param2:Handler = null, param3:Handler = null, param4:Handler = null, param5:Boolean = true) : void
        {
            var itemCount:int;
            var itemloaded:int;
            var totalSize:int;
            var items:Array;
            var loadAssetsComplete:Function;
            var loadAssetsProgress:Function;
            var item:Object;
            var arr:* = param1;
            var complete:* = param2;
            var progress:* = param3;
            var error:* = param4;
            var isCacheContent:* = param5;
            loadAssetsComplete = function (param1:Object, param2) : void
            {
                var _loc_4:* = itemloaded + 1;
                itemloaded = _loc_4;
                param1.progress = 1;
                if (itemloaded == itemCount)
                {
                    if (complete != null)
                    {
                        complete.execute();
                    }
                }
                return;
            }// end function
            ;
            loadAssetsProgress = function (param1:Object, param2:Number) : void
            {
                var _loc_3:Number = NaN;
                var _loc_4:int = 0;
                var _loc_5:Object = null;
                if (progress != null)
                {
                    param1.progress = param2;
                    _loc_3 = 0;
                    _loc_4 = 0;
                    while (_loc_4 < itemCount)
                    {
                        
                        _loc_5 = items[_loc_4];
                        _loc_3 = _loc_3 + _loc_5.size * _loc_5.progress;
                        _loc_4++;
                    }
                    progress.executeWith([_loc_3 / totalSize]);
                }
                return;
            }// end function
            ;
            itemCount = arr.length;
            itemloaded;
            totalSize;
            items;
            var i:int;
            while (i < itemCount)
            {
                
                item = arr[i];
                if (item is String)
                {
                    item;
                }
                item.progress = 0;
                totalSize = totalSize + item.size;
                items.push(item);
                this.load(item.url, item.type, item.priority, new Handler(loadAssetsComplete, [item]), new Handler(loadAssetsProgress, [item]), error, isCacheContent);
                i = (i + 1);
            }
            return;
        }// end function

        public function lock() : void
        {
            this._lock = true;
            return;
        }// end function

        public function unlock() : void
        {
            this._lock = false;
            this.checkNext();
            return;
        }// end function

    }
}
